<?php
if(!defined('DEDEINC')) exit('Request Error!');
require_once(DEDEINC.'/payment/xorpay.lib.php');
helper('xorpay');
/**
 * xorpay接口类
 * 支持支付宝、微信扫码支付，公众号支付
 * author：六久阁  www.lol9.cn
 * Class xorpay
 */
class xorpay
{
    var $dsql;
    var $mid;
    var $ver;
    var $return_url;

    /**
     * 构造函数
     *
     * @access  public
     * @param
     *
     * @return void
     */
    function xorpay()
    {
        global $dsql;
        $this->dsql = $dsql;
    }

    function __construct()
    {
        $this->xorpay();
    }

    function setVer($ver='')
    {
        $this->ver = floatval($ver);
    }

    /**
     *  设定接口会送地址
     *
     *
     * @param     string  $returnurl  会送地址
     * @return    void
     */
    function SetReturnUrl($returnurl='')
    {
        if (!empty($returnurl))
        {
            $this->return_url = $returnurl;
        }
    }

    function getConfig()
    {
        $txt = DEDEDATA.'/module/xorpay.txt';
        $content = array();
        if(file_exists($txt))
        {
            $fp = fopen($txt,'r');
            $content = fread($fp, filesize($txt));
            fclose($fp);
            $content = unserialize($content);
        }
        return $content;
    }

    /**
     * 生成支付代码
     * @param   array   $order      订单信息
     * @param   array   $payment    支付方式信息
     */
    function GetCode($order, $payment)
    {
        global $cfg_basehost,$cfg_cmspath,$cfg_soft_lang,$cfg_phpurl;
        require_once(DEDEINC.'/memberlogin.class.php');
        $cfg_ml = new MemberLogin();
        $charset = $cfg_soft_lang;
        $phpurl = strpos($cfg_phpurl,'http')===0 ? $cfg_phpurl : getLocalDomain().$cfg_phpurl;
        //对于二级目录的处理
        if(!empty($cfg_cmspath)) $cfg_basehost = $cfg_basehost.'/'.$cfg_cmspath;
        if($order['price']) $order['total_fee'] = $order['price'];
        

        //添加订单记录
        $order['mid'] = $order['mid'] ? intval($order['mid']) : intval($cfg_ml->M_ID);
        $order['aid'] = $order['aid'] ? intval($order['aid']) : 0;
        $order['subject'] = $order['subject'] ? $order['subject'] : '订单号：'.$order['out_trade_no'];
        $ip = GetIP();
        $orderRow = $this->dsql->GetOne("select * from `#@__xororder` where out_trade_no = '".$order['out_trade_no']."'");
        if(!$orderRow){
            $query = "INSERT INTO `#@__xororder` (`subject`,`out_trade_no`,`mid`,`aid`,`ip`,`total_fee`,`created_at`) VALUES ('".$order['subject']."','".$order['out_trade_no']."','".$order['mid']."','".$order['aid']."','".$ip."','".$order['total_fee']."','".date('Y-m-d H:i:s')."')";
            $result = $this->dsql->ExecuteNoneQuery($query);
            if($result!==true) exit('insert order error');
        }
        if($orderRow && in_array($orderRow['status'],array(0,2))) exit('This order has been paid');
        $payService = new XorpayService();  
        $payService->setAid($payment['aid']);
        $payService->setKey($payment['appkey']);
        $payService->setTotalFee($order['total_fee']);
        $payService->setOutTradeNo($order['out_trade_no']);
        $payService->setBody($order['subject']);
        $payService->setNotifyUrl($payment['notify_url']);
        $payService->setPostUrl($phpurl.'/xorpay.php');
        if($this->isWeixin() && $payment['pay_channel']!='支付宝'){            
            $backUrl = $phpurl.'/xorpay_pay.php?total_fee='.$order['total_fee'].'&out_trade_no='.$order['out_trade_no'];
            if(!$openid) $openid = $payService->getOpenid($backUrl);            
            $sql = "UPDATE `#@__xororder` SET `pay_type`='weixin' WHERE `out_trade_no`='".$order['out_trade_no']."' and status = 1";
            $this->dsql->ExecuteNoneQuery($sql);
            $jumpUrl = $phpurl.'/xorpay.php?action=jspay&totalFee='.$order['total_fee'].'&body='.$order['subject'].'&outTradeNo='.$order['out_trade_no'].'&openid='.$openid;
            header("Location:{$jumpUrl}");
            exit();
        }elseif($this->isMobile() && $payment['pay_channel']!='微信'){
            $sql = "UPDATE `#@__xororder` SET `pay_type`='alipay' WHERE `out_trade_no`='".$order['out_trade_no']."' and status = 1";
            $this->dsql->ExecuteNoneQuery($sql);



            $sHtml = $payService->getAlipayH5Url();
            $head = '<!DOCTYPE html><html><head><meta charset="'.$charset.'" /><title>跳转到支付页面</title><style type="text/css">html,body,div,h1,*{margin:0;padding:0;}body{background-color:#fefefe;color:#333}.box{width:580px;margin:0 auto;}h1{ font-size:20px;text-align:center;padding-top:160px;margin-top:30%;font-weight:normal;}</style></head><body><div class="box"><h1>正在跳转到支付页面...</h1></div>';
            $html = $head.$sHtml.'</body></html>';
            echo $html;exit();
        }else{
			$sHtml = $payService->gotoPay();
			$head = '<!DOCTYPE html><html><head><meta charset="'.$charset.'" /><title>跳转到支付页面</title><style type="text/css">html,body,div,h1,*{margin:0;padding:0;}body{background-color:#fefefe;color:#333}.box{width:580px;margin:0 auto;}h1{	font-size:20px;text-align:center;padding-top:160px;margin-top:30%;font-weight:normal;}</style></head><body><div class="box"><h1>正在跳转到支付页面...</h1></div>';
			$html = $head.$sHtml.'</body></html>';
			echo $html;exit();
		}
    }


    function isMobile() {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
            return true;
        }
        if($this->isWeixin()){
            return true;
        }
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset($_SERVER['HTTP_VIA'])) {
            // 找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
        }
        // 脑残法，判断手机发送的客户端标志,兼容性有待提高。其中'MicroMessenger'是电脑微信
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = array('nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile','MicroMessenger');
            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
                return true;
            }
        }
        // 协议法，因为有可能不准确，放到最后判断
        if (isset ($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }
        return false;
    }

    function isWeixin() {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
            return true;
        } else {
            return false;
        }
    }



    /**
     * 响应操作
     */
    function respond()
    {
        global $cfg_cmspath,$cfg_phpurl;
        if (!empty($_POST))
        {
            foreach($_POST as $key => $data)
            {
                $_GET[$key] = $data;
            }
        }
        /* 引入配置文件 */
        $code = preg_replace( "#[^0-9a-z-]#i", "", $_GET['code'] );
        require DEDEDATA.'/payment/'.$code.'.php';
        $service = new XorpayService();
        $service->setKey($payment['appkey']);
        $result = $service->check($_POST);
        if($result===false){
            exit('sign error');
        }
        /* 取得订单号 */
        $_GET['total_fee'] = $_GET['pay_price'];
		$_GET['order_id'] = str_replace('-A','',$_GET['order_id']);
		$_GET['order_id'] = str_replace('-W','',$_GET['order_id']);
        $order_sn = trim(addslashes($_GET['order_id']));
        $phpurl = strpos($cfg_phpurl,'http')===0 ? $cfg_phpurl : getLocalDomain().$cfg_phpurl;
        $_POST['pay_at'] = $_GET['pay_at'] = $_GET['pay_time'];
        /*判断订单类型*/		
        if(preg_match ("/S-P[0-9]+RN[0-9]/",$order_sn)) {
            //检查支付金额是否相符
            $row = $this->dsql->GetOne("SELECT * FROM #@__shops_orders WHERE oid = '{$order_sn}'");
            if ($row['priceCount'] != $_GET['total_fee'])
            {
                $this->log_result("支付失败，支付金额与商品总价不相符!");
                return $msg = "支付失败，支付金额与商品总价不相符!";
            }
            $this->mid = $row['userid'];
            $ordertype="goods";
        }else if (preg_match ("/M[0-9]+T[0-9]+RN[0-9]/", $order_sn)){
            $row = $this->dsql->GetOne("SELECT * FROM #@__member_operation WHERE buyid = '{$order_sn}'");
            //获取订单信息，检查订单的有效性
            if(!is_array($row)||$row['sta']==2){
                header("Location:{$phpurl}/xorpay.php?action=return&out_trade_no={$order_sn}&total_fee=".$_GET['total_fee']);
                exit();
            }
            elseif($row['money'] != $_GET['total_fee']){
                $this->log_result("支付失败，支付金额与商品总价不相符2!");
                return $msg = "支付失败，支付金额与商品总价不相符!";
            }
            $ordertype = "member";
            $product =    $row['product'];
            $pname= $row['pname'];
            $pid=$row['pid'];
            $this->mid = $row['mid'];
        } else {
            $row = $this->dsql->GetOne("SELECT * FROM #@__xororder WHERE out_trade_no = '{$order_sn}'");
            if(!is_array($row)||$row['status']==0){
                header("Location:{$phpurl}/xorpay.php?action=return&out_trade_no={$order_sn}&total_fee=".$_GET['total_fee']);
                exit();
            }
            elseif($row['total_fee'] != $_GET['total_fee']){
                $this->log_result("支付失败，支付金额与商品总价不相符3!");
                return $msg = "支付失败，支付金额与商品总价不相符!";
            }
            $ordertype = 'zan';
        }
        $this->success_xor($_GET);
        if($ordertype=="goods" && $_POST['pay_at']){
            if($this->success_db($order_sn)){
                header("Location:{$phpurl}/xorpay.php?action=return&out_trade_no={$order_sn}&total_fee=".$_GET['total_fee']);
                exit();
            }
            else  return $msg = "支付失败！<br> <a href='/'>返回主页</a> <a href='/member'>会员中心</a>";
        } else if ( $ordertype=="member"  && $_POST['pay_at']) {
            $oldinf = $this->success_mem($order_sn,$pname,$product,$pid);
            header("Location:{$phpurl}/xorpay.php?action=return&out_trade_no={$order_sn}&total_fee=".$_GET['total_fee']);
            exit();
        }else if ( $ordertype=="zan" ) {
            header("Location:{$phpurl}/xorpay.php?action=return&out_trade_no={$order_sn}&total_fee=".$_GET['total_fee']);
            exit();
        }

    }

    /*处理有赞订单*/
    function success_xor($data)
    {
        global $cfg_soft_lang;
        if(empty($data['pay_at'])) return;
         $detail = str_replace('\"','"',$data['detail']);
        $transactionTid =$data['aoid'];
        $buyer ='';
        $bankType = '';
        if($detail){
            $transactionTid = $detail['transaction_id'];
            $buyer = $detail['buyer'];
            $bankType = $detail['bank_type'];
        }
        $order_sn = $data['order_id'];
        //获取订单信息，检查订单的有效性
        $row = $this->dsql->GetOne("SELECT * FROM #@__xororder WHERE out_trade_no='$order_sn' ");
        if($row['status'] == 0)
        {
            return TRUE;
        }
        /* 改变订单状态_支付成功 */
        helper('cache');
        SetCache('order',$order_sn,0);
        $sql = "UPDATE `#@__xororder` SET `status`=0,`outer_tid`='{$data['aoid']}',`transaction_tid`='{$transactionTid}',`pay_at`='{$data['pay_at']}',`buyer_info`='{$buyer}',`bank_type`='{$bankType}' WHERE `out_trade_no`='$order_sn'";
        if($this->dsql->ExecuteNoneQuery($sql))
        {
            $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
            return TRUE;
        } else {
            $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
            return FALSE;
        }
    }

    /*处理物品交易*/
    function success_db($order_sn)
    {
        //获取订单信息，检查订单的有效性
        $row = $this->dsql->GetOne("SELECT state FROM #@__shops_orders WHERE oid='$order_sn' ");
        if($row['state'] > 0)
        {
            return TRUE;
        }
        /* 改变订单状态_支付成功 */
        $sql = "UPDATE `#@__shops_orders` SET `state`='1' WHERE `oid`='$order_sn' AND `userid`='".$this->mid."'";
        if($this->dsql->ExecuteNoneQuery($sql))
        {
            $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
            return TRUE;
        } else {
            $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
            return FALSE;
        }
    }

    /*处理点卡，会员升级*/
    function success_mem($order_sn,$pname,$product,$pid)
    {
        //更新交易状态为已付款
        $sql = "UPDATE `#@__member_operation` SET `sta`='1' WHERE `buyid`='$order_sn' AND `mid`='".$this->mid."'";
        $this->dsql->ExecuteNoneQuery($sql);

        /* 改变点卡订单状态_支付成功 */
        if($product=="card")
        {
            $row = $this->dsql->GetOne("SELECT cardid FROM #@__moneycard_record WHERE ctid='$pid' AND isexp='0' ");;
            //如果找不到某种类型的卡，直接为用户增加金币
            if(!is_array($row))
            {
                $nrow = $this->dsql->GetOne("SELECT num FROM #@__moneycard_type WHERE pname = '{$pname}'");
                $dnum = $nrow['num'];
                if(empty($nrow['num'])){
                    $nrow = $this->dsql->GetOne("SELECT money as num FROM `#@__member_operation` WHERE `buyid`='{$order_sn}'");
                }
                $sql1 = "UPDATE `#@__member` SET `money`=money+'{$nrow['num']}' WHERE `mid`='".$this->mid."'";
                $oldinf ="已经充值了".$nrow['num']."金币到您的帐号！";
            } else {
                $cardid = $row['cardid'];
                $sql1=" UPDATE #@__moneycard_record SET uid='".$this->mid."',isexp='1',utime='".time()."' WHERE cardid='$cardid' ";
                $oldinf='您的充值密码是：<font color="green">'.$cardid.'</font>';
            }
            //更新交易状态为已关闭
            $sql2=" UPDATE #@__member_operation SET sta=2,oldinfo='$oldinf' WHERE buyid='$order_sn'";
            if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
            {
                $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
                return $oldinf;
            } else {
                $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
                return "支付失败！";
            }
            /* 改变会员订单状态_支付成功 */
        } else if ( $product=="member" ){
            $row = $this->dsql->GetOne("SELECT rank,exptime FROM #@__member_type WHERE aid='$pid' ");
            $rank = $row['rank'];
            $exptime = $row['exptime'];
            /*计算原来升级剩余的天数*/
            $rs = $this->dsql->GetOne("SELECT uptime,exptime FROM #@__member WHERE mid='".$this->mid."'");
            if($rs['uptime']!=0 && $rs['exptime']!=0 )
            {
                $nowtime = time();
                $mhasDay = $rs['exptime'] - ceil(($nowtime - $rs['uptime'])/3600/24) + 1;
                $mhasDay=($mhasDay>0)? $mhasDay : 0;
            }
            //获取会员默认级别的金币和积分数
            $memrank = $this->dsql->GetOne("SELECT money,scores FROM #@__arcrank WHERE rank='$rank'");
            //更新会员信息
            $sql1 =  " UPDATE #@__member SET rank='$rank',money=money+'{$memrank['money']}',
                       scores=scores+'{$memrank['scores']}',exptime='$exptime'+'$mhasDay',uptime='".time()."' 
                       WHERE mid='".$this->mid."'";
            //更新交易状态为已关闭
            $sql2=" UPDATE #@__member_operation SET sta='2',oldinfo='会员升级成功!' WHERE buyid='$order_sn' ";
            if($this->dsql->ExecuteNoneQuery($sql1) && $this->dsql->ExecuteNoneQuery($sql2))
            {
                $this->log_result("verify_success,订单号:".$order_sn); //将验证结果存入文件
                return "会员升级成功！";
            } else {
                $this->log_result ("verify_failed,订单号:".$order_sn);//将验证结果存入文件
                return "会员升级失败！";
            }
        }
    }

    function  log_result($word)
    {
        $fp = fopen(DEDEDATA."/payment/log.txt","a");
        flock($fp, LOCK_EX) ;
        fwrite($fp,$word.",执行日期:".strftime("%Y-%m-%d %H:%I:%S",time())."\r\n");
        flock($fp, LOCK_UN);
        fclose($fp);
    }
}
